-module(couchdb).

-include("sew_app.hrl").

-compile(export_all).

%% erlang_couchdb:create_database({"localhost", 5984}, "iplaywow").
%% erlang_couchdb:database_info({"localhost", 5984}, "iplaywow").
%% erlang_couchdb:server_info({"localhost", 5984}).
%% erlang_couchdb:create_document({"localhost", 5984}, "iplaywow", [{<<"name">>, <<"Korale">>}, {<<"type">>}, <<"character">>}]).
%% erlang_couchdb:retrieve_document({"localhost", 5984}, "iplaywow", "0980...").
%% erlang_couchdb:update_document({"localhost", 5984}, "iplaywow", "0980...", [{<<"_rev">>, <<"3419...">>}, {<<"name">>, <<"Korale">>}, {<<"level">>, <<"70">>}, {<<"type">>}, <<"character">>}]).
%% erlang_couchdb:delete_document({"localhost", 5984}, "iplaywow", "1fd0...", "1193...").
%% erlang_couchdb:create_view({"localhost", 5984}, "iplaywow", "characters", <<"javascript">>, [{<<"realm">>, <<"function(doc) { if (doc.type == 'character')  emit(doc.realm_full, null) }">>}]).
%% erlang_couchdb:invoke_view({"localhost", 5984}, "iplaywow", "characters", "realm", [{"key", "\"Medivh-US\""}]).

create_database(Name) ->
	erlang_couchdb:create_database(?DB_HOST, Name).
create_database(Server, Name) ->
	erlang_couchdb:create_database(Server, Name).

database_info(Name) ->
	erlang_couchdb:database_info(?DB_HOST, Name).
database_info(Server, Name) ->
	erlang_couchdb:database_info(Server, Name).

server_info() ->
	erlang_couchdb:server_info(?DB_HOST).
server_info(Server) ->
	erlang_couchdb:server_info(Server).

create_document({ID, Doc}) ->
	erlang_couchdb:create_document(?DB_HOST, ?DB_DATABASE, ID, Doc);
create_document(Doc) ->
	erlang_couchdb:create_document(?DB_HOST, ?DB_DATABASE, Doc).

create_document(Db, {ID, Doc}) ->
	erlang_couchdb:create_document(?DB_HOST, Db, ID, Doc);
create_document(Db, Doc) ->
	erlang_couchdb:create_document(?DB_HOST, Db, Doc).

create_document(Host, Db, {ID, Doc}) ->
	erlang_couchdb:create_document(Host, Db, ID, Doc);
create_document(Server, Db, Doc) ->
	erlang_couchdb:create_document(Server, Db, Doc).

retrieve_document(ID) ->
	retrieve_document(?DB_HOST, ?DB_DATABASE, ID).
retrieve_document(Db, ID) ->
	retrieve_document(?DB_HOST, Db, ID).

retrieve_document(Server, Db, ID) when is_binary(ID) ->
	{ok, IDString} = utf8:from_binary(ID),
	retrieve_document(?DB_HOST, Db, IDString);
retrieve_document(Server, Db, ID) ->
	erlang_couchdb:retrieve_document(Server, Db, ID).

update_document(ID, Rev, Doc) ->
	erlang_couchdb:update_document(?DB_HOST, ?DB_DATABASE, ID, [{<<"_rev">>, list_to_binary(Rev)} | Doc]).
update_document(Db, ID, Rev, Doc) ->
	erlang_couchdb:update_document(?DB_HOST, Db, ID, [{<<"_rev">>, list_to_binary(Rev)} | Doc]).
update_document(Server, Db, ID, Rev, Doc) ->
	erlang_couchdb:update_document(Server, Db, ID, [{<<"_rev">>, list_to_binary(Rev)} | Doc]).

delete_document(ID, Rev) ->
	erlang_couchdb:delete_document(?DB_HOST, ?DB_DATABASE, ID, Rev).
delete_document(Db, ID, Rev) ->
	erlang_couchdb:delete_document(?DB_HOST, Db, ID, Rev).
delete_document(Server, Db, ID, Rev) ->
	erlang_couchdb:delete_document(Server, Db, ID, Rev).

create_view(DocName, ViewList) when is_list(ViewList) ->
	erlang_couchdb:create_view(?DB_HOST, ?DB_DATABASE, DocName, <<"javascript">>, ViewList).
	
create_view(DocName, ViewName, Data) ->
	erlang_couchdb:create_view(?DB_HOST, ?DB_DATABASE, DocName, <<"javascript">>, [{ViewName, Data}]).
create_view(DocName, Type, ViewName, Data) ->
	erlang_couchdb:create_view(?DB_HOST, ?DB_DATABASE, DocName, Type, [{ViewName, Data}]).
create_view(Db, DocName, Type, ViewName, Data) ->
	erlang_couchdb:create_view(?DB_HOST, Db, DocName, Type, [{ViewName, Data}]).
create_view(Server, Db, DocName, Type, ViewName, Data) ->
	erlang_couchdb:create_view(Server, Db, DocName, Type, [{ViewName, Data}]).

invoke_view(DocName, ViewName) ->
	erlang_couchdb:invoke_view(?DB_HOST, ?DB_DATABASE, DocName, ViewName, []).
invoke_view(DocName, ViewName, Keys) ->
	erlang_couchdb:invoke_view(?DB_HOST, ?DB_DATABASE, DocName, ViewName, Keys).
invoke_view(Db, DocName, ViewName, Keys) ->
	erlang_couchdb:invoke_view(?DB_HOST, Db, DocName, ViewName, Keys).
invoke_view(Server, Db, DocName, ViewName, Keys) ->
	erlang_couchdb:invoke_view(Server, Db, ViewName, Keys).


single_record(Response) ->
	case Response of 
		{json,{struct, L}} ->
			case proplists:get_value(<<"rows">>, L, {}) of
				[{struct, Data} = Record] ->
					Record;
				_ ->
					undefined
			end;
		_ ->
			undefined
	end.
			
get_value(Doc, Key) ->
	get_value(Doc, Key, "").
get_value({struct, L}, Key, DefaultValue) ->
	Values = proplists:get_value(<<"value">>, L, []),
	case Values of
		[] ->
			DefaultValue;
		{struct, ValueList} ->
			proplists:get_value(Key, ValueList, DefaultValue)
	end;
get_value(_, Key, DefaultValue) ->
	DefaultValue.
	
get_id(Doc) ->
	get_id(Doc, "").
get_id({struct, L}, DefaultValue) ->
	binary_to_list(proplists:get_value(<<"id">>, L, DefaultValue));
get_id(_, DefaultValue) ->
	DefaultValue.

get_rev(Doc) ->
	get_rev(Doc, "").
get_rev({struct, L} = Doc, DefaultValue) ->
	binary_to_list(get_value(Doc, <<"_rev">>, DefaultValue));
get_rev(_, DefaultValue) ->
	DefaultValue.
	
get_revs(ID) ->
	get_revs(?DB_HOST, ?DB_DATABASE, ID).
get_revs(Db, ID) ->
	get_revs(?DB_HOST, Db, ID).
get_revs(Server, Db, ID) ->
	{ServerName, Port} = Server,
	Type = "GET",
	URI = lists:concat(["/", ?DB_DATABASE, "/", ID, "?", "revs_info=true"]),
	Body = <<>>,
	Rows = erlang_couchdb:raw_request(Type, ServerName, Port, URI, Body),
	%%Rows.a(Rows) -> Rows,
	case Rows of
		{json, {struct, PropList}} ->
			Revs = proplists:get_value(<<"_revs_info">>, PropList, []),
			case Revs of
				[] ->
					[];
				RevList ->
					get_revision_list(RevList)
			end;
		_ ->
			[]
	end.

get_revision_list(RevList) ->
	get_revision_list(RevList, []).
	
get_revision_list([{struct, PropList}|T], Acc) ->
	Rev = binary_to_list(proplists:get_value(<<"rev">>, PropList, <<"">>)),
	Status = binary_to_list(proplists:get_value(<<"status">>, PropList, <<"">>)),
	get_revision_list(
		T,
		Acc ++ [{Rev, Status}]
	);
get_revision_list([], Acc) ->
	Acc.